/*
 * @Author: your name
 * @Date: 2021-05-17 15:19:56
 * @LastEditTime: 2021-05-17 15:30:05
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /vite-project/src/utils/hepler/treeHelper.ts
 */

interface TreeHelperConfig {
    id: string;
    children: string;
    pid: string;
}

const DEFAULT_CONFIG: TreeHelperConfig = {
    id: 'id',
    children: 'children',
    pid: 'pid',
};

/* 知识点:   Object.assign方法用于对象的合并，将源对象（source）的所有可枚举属性，复制到目标对象（target)：Object.assign(target, ...sources)
            Object.assign方法的第一个参数是目标对象，后面的参数都是源对象
            注意，如果目标对象与源对象有同名属性，或多个源对象有同名属性，则后面的属性会覆盖前面的属性。如果只有一个参数，Object.assign会直接返回该参数。
*/

const getConfig = (config: Partial<TreeHelperConfig>) =>
    Object.assign({}, DEFAULT_CONFIG, config);

export function filter<T = any>(
    tree: T[],
    func: (n: T) => boolean,
    config: Partial<TreeHelperConfig> = {}
): T[] {
    config = getConfig(config);
    const children = config.children as string;
    function listFilter(list: T[]) {
        return list
            .map((node: any) => ({ ...node }))
            .filter((node) => {
                node[children] = node[children] && listFilter(node[children]);
                return func(node) || (node[children] && node[children].length);
            });
    }
    return listFilter(tree);
}
